package com.example.taskscheduling.controller;

import com.example.taskscheduling.service.AsyncTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * 任务调度控制器
 * 提供HTTP接口用于触发异步任务，演示异步方法的调用与执行流程
 */
@RestController // 标识为REST风格控制器，方法返回值直接作为HTTP响应内容
public class TaskController {

    /**
     * 注入异步任务服务
     * 用于调用异步执行的短信发送方法
     */
    @Autowired
    private AsyncTaskService asyncTaskService;

    /**
     * 触发短信验证码发送的HTTP接口
     * 调用异步方法发送短信，无需等待方法执行完成即可返回响应
     * 解决耗时操作导致的接口响应缓慢问题
     *
     * @return 包含当前时间的响应字符串，表明接口已成功触发异步任务
     * @throws InterruptedException 当异步方法执行被中断时可能抛出的异常
     */
    @RequestMapping("/sendSMS") // 映射HTTP请求路径，支持GET等请求方式访问
    public String sendSMS() throws InterruptedException {
        // 调用异步任务服务中的短信发送方法
        // 由于方法被@Async注解标记，将在独立线程中执行，不会阻塞当前请求处理线程
        asyncTaskService.sendSMS();

        // 立即返回响应，不等待异步方法执行完成
        // 响应内容包含当前时间（去除纳秒，便于阅读），表明接口调用成功
        return LocalDateTime.now().withNano(0) + "成功调用短信验证码服务";
    }

    /**
     * 触发销售额统计的HTTP接口
     * 异步调用多个地区的销售额统计方法，并汇总结果
     * 演示如何使用Future获取异步任务的返回值并进行处理
     *
     * @return 包含当前时间的响应字符串，表明统计任务已成功执行
     * @throws InterruptedException 当等待异步结果时线程被中断抛出的异常
     * @throws ExecutionException 当异步任务执行过程中发生异常时抛出的异常
     */
    @RequestMapping("/statistics") // 映射HTTP请求路径，支持通过该路径触发销售额统计
    public String salesStatistics() throws InterruptedException, ExecutionException {
        // 记录控制器方法开始执行的时间戳，用于计算总耗时
        long st = System.currentTimeMillis();

        // 异步调用北京地区的销售额统计方法
        // 方法立即返回Future对象，代表异步任务的结果占位符，此时任务在后台执行
        Future<Integer> future1 = asyncTaskService.salesStatistics("北京");

        // 异步调用上海地区的销售额统计方法
        // 两个统计任务将并行执行，提高效率（总耗时约等于耗时较长的单个任务）
        Future<Integer> future2 = asyncTaskService.salesStatistics("上海");

        // 调用Future的get()方法获取异步任务的结果
        // get()方法会阻塞当前线程，直到对应的异步任务执行完成并返回结果
        // 此处先获取北京地区结果，再获取上海地区结果，然后求和得到总销售额
        Integer result = future1.get() + future2.get();

        // 记录控制器方法执行结束的时间戳
        long et = System.currentTimeMillis();

        // 打印统计总计结果和控制器层的总耗时
        // 总耗时应接近两个异步任务中耗时较长的那个（因并行执行）
        System.out.println("统计总计：" + result + "元，控制层调用总耗时：" + (et - st) + "ms");

        // 返回响应字符串，包含当前时间（去除纳秒），表明统计任务已成功执行
        return LocalDateTime.now().withNano(0) + "成功执行销售金额统计";
    }
}